#include "Tests.h"
#include <math.h>
// Tests para las factorizaciones

Matriz crearMatrizA(char* archivo){

    FILE* datos = fopen(archivo, "r");
    int n = cargarParam(datos);
    int m0 = cargarParam(datos);
    int ml = cargarParam(datos);
    int mp = cargarParam(datos);
    int pesados[n+1], livianos[n+1], coeficientes[n+1];
    for(int i=1; i<=n; i++)        coeficientes[i] = cargarParam(datos);

    for(int i=1; i<=n; i++)        livianos[i] = cargarParam(datos);

    for(int i=1; i<=n; i++)        pesados[i] = cargarParam(datos);

    Matriz K =  crearMatrizK(n,coeficientes);

    Matriz M = crearMatrizM(n,m0,ml,mp, livianos, pesados);

    M.invertir();

    Matriz A = M.multiplicar(K);

    return A;
}
void AlgoritmoQR(int iteraciones, double error, Matriz& A){
    double anterior = 0;
    int ultimaIt = 0;
    for(int i=0; i<iteraciones && error < fabs(A.get(1,1) - anterior); i++)
    {
        anterior = A.get(1,1);
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
        ultimaIt = i;
    }
    if(error == 0)cout << "    |    " << fabs(A.get(1,1) - anterior) << endl;
    if(iteraciones == 100000000)cout << "  |   " << ultimaIt << endl;
}

void testReflexionesIteracionesVariandoCantCeros(){    // veo la cantidad de iteraciones variando la cantidad de ceros que tiene la triangular inferior de A
}
void testRotacionesIteracionesVariandoCantCeros(){     // veo la cantidad de iteraciones variando la cantidad de ceros que tiene la triangular inferior de A
}
void testReflexionesIteracionesVariandoTamanoMatriz(){ // veo la cantidad de iteraciones variando el tamaño de la matriz
    char edificio3[]="../archivosPrueba/prueba3.txt";
    cout << "Tamaño A   |   Iteraciones" << endl;
    cout << 3 << "  |   ";
    Matriz A = crearMatrizA(edificio3);
    calcularQRReflexiones(A, true);

    char edificio5[]="../archivosPrueba/prueba5.txt";
    cout << 5 << "  |   ";
    A = crearMatrizA(edificio5);
    calcularQRReflexiones(A, true);

    char edificio10[]="../archivosPrueba/prueba10.txt";
    cout << 10 << "  |   ";
    A = crearMatrizA(edificio10);
    calcularQRReflexiones(A, true);

    char edificio20[]="../archivosPrueba/prueba20.txt";
    cout << 20 << "  |   ";
    A = crearMatrizA(edificio20);
    calcularQRReflexiones(A, true);

    char edificioTest0[]="../archivosPrueba/Test0";
    A = crearMatrizA(edificioTest0);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest1[]="../archivosPrueba/Test1";
    A = crearMatrizA(edificioTest1);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest2[]="../archivosPrueba/Test2";
    A = crearMatrizA(edificioTest2);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest3[]="../archivosPrueba/Test3";
    A = crearMatrizA(edificioTest3);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest4[]="../archivosPrueba/Test4";
    A = crearMatrizA(edificioTest4);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest5[]="../archivosPrueba/Test5";
    A = crearMatrizA(edificioTest5);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest6[]="../archivosPrueba/Test6";
    A = crearMatrizA(edificioTest6);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest7[]="../archivosPrueba/Test7";
    A = crearMatrizA(edificioTest7);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest8[]="../archivosPrueba/Test8";
    A = crearMatrizA(edificioTest8);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest9[]="../archivosPrueba/Test9";
    A = crearMatrizA(edificioTest9);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest10[]="../archivosPrueba/Test10";
    cout << "Tamaño A   |   Iteraciones" << endl;
    A = crearMatrizA(edificioTest10);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest11[]="../archivosPrueba/Test11";
    A = crearMatrizA(edificioTest11);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest12[]="../archivosPrueba/Test12";
    A = crearMatrizA(edificioTest12);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest13[]="../archivosPrueba/Test13";
    A = crearMatrizA(edificioTest13);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest14[]="../archivosPrueba/Test14";
    A = crearMatrizA(edificioTest14);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest15[]="../archivosPrueba/Test15";
    A = crearMatrizA(edificioTest15);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest16[]="../archivosPrueba/Test16";
    A = crearMatrizA(edificioTest16);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest17[]="../archivosPrueba/Test18";
    A = crearMatrizA(edificioTest17);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest18[]="../archivosPrueba/Test18";
    A = crearMatrizA(edificioTest18);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest19[]="../archivosPrueba/Test19";
    A = crearMatrizA(edificioTest19);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);

    char edificioTest20[]="../archivosPrueba/Test20";
    A = crearMatrizA(edificioTest20);
    cout << A.size() << "  |   ";
    calcularQRReflexiones(A, true);
}
void testRotacionesIteracionesVariandoTamanoMatriz(){   // veo la cantidad de iteraciones variando el tamaño de la matriz
    char edificio3[]="../archivosPrueba/prueba3.txt";
    cout << "Tamaño A   |   Iteraciones" << endl;
    cout << 3 << "  |   ";
    Matriz A = crearMatrizA(edificio3);
    calcularQRRotaciones(A, true);

    char edificio5[]="../archivosPrueba/prueba5.txt";
    cout << "Tamaño A   |   Iteraciones" << endl;
    cout << 5 << "  |   ";
    A = crearMatrizA(edificio5);
    calcularQRRotaciones(A, true);

    char edificio10[]="../archivosPrueba/prueba10.txt";
    cout << "Tamaño A   |   Iteraciones" << endl;
    cout << 10 << "  |   ";
    A = crearMatrizA(edificio10);
    calcularQRRotaciones(A, true);

    char edificio20[]="../archivosPrueba/prueba20.txt";
    cout << "Tamaño A   |   Iteraciones" << endl;
    cout << 20 << "  |   ";
    A = crearMatrizA(edificio20);
    calcularQRRotaciones(A, true);

    char edificioTest0[]="../archivosPrueba/Test0";
    A = crearMatrizA(edificioTest0);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest1[]="../archivosPrueba/Test1";
    A = crearMatrizA(edificioTest1);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest2[]="../archivosPrueba/Test2";
    A = crearMatrizA(edificioTest2);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest3[]="../archivosPrueba/Test3";
    A = crearMatrizA(edificioTest3);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest4[]="../archivosPrueba/Test4";
    A = crearMatrizA(edificioTest4);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest5[]="../archivosPrueba/Test5";
    A = crearMatrizA(edificioTest5);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest6[]="../archivosPrueba/Test6";
    A = crearMatrizA(edificioTest6);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest7[]="../archivosPrueba/Test7";
    A = crearMatrizA(edificioTest7);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest8[]="../archivosPrueba/Test8";
    A = crearMatrizA(edificioTest8);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest9[]="../archivosPrueba/Test9";
    A = crearMatrizA(edificioTest9);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest10[]="../archivosPrueba/Test10";
    cout << "Tamaño A   |   Iteraciones" << endl;
    A = crearMatrizA(edificioTest10);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest11[]="../archivosPrueba/Test11";
    A = crearMatrizA(edificioTest11);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest12[]="../archivosPrueba/Test12";
    A = crearMatrizA(edificioTest12);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest13[]="../archivosPrueba/Test13";
    A = crearMatrizA(edificioTest13);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest14[]="../archivosPrueba/Test14";
    A = crearMatrizA(edificioTest14);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest15[]="../archivosPrueba/Test15";
    A = crearMatrizA(edificioTest15);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest16[]="../archivosPrueba/Test16";
    A = crearMatrizA(edificioTest16);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest17[]="../archivosPrueba/Test18";
    A = crearMatrizA(edificioTest17);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest18[]="../archivosPrueba/Test18";
    A = crearMatrizA(edificioTest18);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest19[]="../archivosPrueba/Test19";
    A = crearMatrizA(edificioTest19);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);

    char edificioTest20[]="../archivosPrueba/Test20";
    A = crearMatrizA(edificioTest20);
    cout << A.size() << "  |   ";
    calcularQRRotaciones(A, true);
}
// Tests para el algoritmo QR

void testAlgoritmoQRValoresUsandoReflexiones(){    // veo los autovalores usando reflexiones para la factorizacion
    char edificio20[]="../archivosPrueba/prueba3.txt";
    Matriz A = crearMatrizA(edificio20);
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
    }
    for(int i = 1; i <= A.size(); i++){
        cout << A.get(i,i) << endl;
    }
}
void testAlgoritmoQRValoresUsandoRotaciones(){    // veo los autovalores usando iteraciones para la factorizacion
    char edificio20[]="../archivosPrueba/prueba3.txt";
    Matriz A = crearMatrizA(edificio20);
    cout << "Valores" << endl;
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRRotaciones(R);
        A = R.multiplicar(Q);
    }
    for(int i = 1; i <= A.size(); i++){
        cout << A.get(i,i) << endl;
    }
}
void testAlgoritmoQRIteracionesVariandoTamanoMatriz(){    // veo las iteraciones usando reflexiones para la factorizacion y variando el tamaño de la matriz A
    char edificio3[]="../archivosPrueba/prueba3.txt";
    Matriz A = crearMatrizA(edificio3);
    calcularQRReflexiones(A);
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
    }
    char edificio5[]="../archivosPrueba/prueba5.txt";
    A = crearMatrizA(edificio5);
    calcularQRReflexiones(A);
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
    }
    char edificio10[]="../archivosPrueba/prueba10.txt";
    A = crearMatrizA(edificio10);
    calcularQRReflexiones(A);
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
    }
    char edificio20[]="../archivosPrueba/prueba20.txt";
    A = crearMatrizA(edificio20);
    calcularQRReflexiones(A);
    for(int i=0; i<500; i++)
    {
        Matriz R = A;
        Matriz Q = calcularQRReflexiones(R);
        A = R.multiplicar(Q);
    }
}
void testAlgoritmoQRErrorVariandoIteraciones(){    // veo el error usando reflexiones para la factorizacion y variando la cantidad de iteraciones
    char edificio20[]="../archivosPrueba/prueba20.txt";
    Matriz A = crearMatrizA(edificio20);
    cout << "Iteraciones  |   Error" << endl;
    int i = 2;
    while(i < 100){
        cout << i;
        AlgoritmoQR(i, 0, A);
        i++;
    }
}
void testAlgoritmoQRIteracionesVariandoError(){    // veo las iteraciones usando reflexiones para la factorizacion y variando el error con el que para
    char edificio20[]="../archivosPrueba/prueba20.txt";
    cout << "Error  |   Iteraciones" << endl;
    double error = 0.1;
    while (error > 0.000000001){
        cout << error;
        Matriz A = crearMatrizA(edificio20);
        AlgoritmoQR(100000000, error, A);
        error = error/10;

    }
}
